package org.byteDance.l054;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author yu
 * @Date 2022/3/5
 */
public class Solution {

    public static void main(String[] args) {

        int[][] ints = {
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12}
        };

        Solution solution = new Solution();
        List<Integer> list = solution.spiralOrder4(ints);
        System.out.println(list);

    }

    public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list = new ArrayList<>();

        if (matrix.length == 0) {
            return list;
        }

        // height：记录二维数组的长度 - 1
        // length：记录二维数组的高度 - 1
        // m：高度的工具变量
        // n：长度的工具变量
        int height = matrix.length - 1, length = matrix[0].length - 1, m = 0, n = 0;

        while (true) {
            for (int i = n; i <= length; i++) {
                list.add(matrix[m][i]);
            }
            if (++m > height) { // 重新定义上边界
                break;
            }
            for (int i = m; i <= height; i++) {
                list.add(matrix[i][length]);
            }
            if (--length < n) { // 重新定义右边界
                break;
            }
            for (int i = length; i >= n; i--) {
                list.add(matrix[height][i]);
            }
            if (--height < m) { // 重新定义下边界
                break;
            }
            for (int i = height; i >= m; i--) {
                list.add(matrix[i][n]);
            }
            if (++n > length) { // 重新定义左边界
                break;
            }
        }

        return list;
    }

    public List<Integer> spiralOrder2(int[][] matrix) {

        List<Integer> list = new ArrayList<>();
        int t = 0, b = matrix.length - 1, l = 0, r = matrix[0].length - 1;

        while (true) {

            // top
            for (int i = t; i <= r; i++) {
                list.add(matrix[t][i]);
            }
            if (++t > b) {
                break;
            }

            // right
            for (int i = t; i <= b; i++) {
                list.add(matrix[i][r]);
            }
            if (--r < l) {
                break;
            }

            // down
            for (int i = r; i >= l; i--) {
                list.add(matrix[b][i]);
            }
            if (--b < t) {
                break;
            }

            // left
            for (int i = b; i >= t; i--) {
                list.add(matrix[b][l]);
            }
            if (++l > r) {
                break;
            }
        }

        return list;
    }

    public List<Integer> spiralOrder3(int[][] matrix) {
        int t = 0, d = matrix.length - 1, l = 0, r = matrix[0].length - 1;
        List<Integer> list = new ArrayList<>();
        while (true) {

            // 上
            for (int i = l; i <= r; i++) {
                list.add(matrix[t][i]);
            }
            if (++t > d) {
                break;
            }

            // 右
            for (int i = t; i <= d; i++) {
                list.add(matrix[i][r]);
            }
            if (--r < l) {
                break;
            }

            // 下
            for (int i = r; i >= l; i--) {
                list.add(matrix[d][i]);
            }
            if (--d < t) {
                break;
            }

            // 左
            for (int i = d; i >= t; i--) {
                list.add(matrix[i][l]);
            }
            if (++l > r) {
                break;
            }
        }
        return list;
    }

    public List<Integer> spiralOrder4(int[][] matrix) {
        int t = 0, d = matrix.length - 1, l = 0, r = matrix[0].length - 1;
        List<Integer> list = new ArrayList<>();
        while (true) {
            
            // 上
            for (int i = l; i <= r; i++) {
                list.add(matrix[t][i]);
            }
            if (++t > d) {
                break;
            }

            // 右
            for (int i = t; i <= d; i++) {
                list.add(matrix[i][r]);
            }
            if (--r < l) {
                break;
            }

            // 下
            for (int i = r; i >= l; i--) {
                list.add(matrix[d][i]);
            }
            if (--d < t) {
                break;
            }

            // 左
            for (int i = d; i >= t; i--) {
                list.add(matrix[i][l]);
            }
            if (++l > r) {
                break;
            }
        }
        return list;
    }

}
